home *** CD-ROM | disk | FTP | other *** search
/ MacWorld UK 2000 March / MW_UK_2000_03.iso / Shareware World / Utilities / Text Processing / Alpha / Tcl / Modes / browserMode.tcl < prev    next >
Encoding:
Text File  |  1999-11-17  |  10.7 KB  |  360 lines  |  [TEXT/ALFA]

  1. #=============================================================================
  2. # Browser mode.
  3. # Alpha cannot do batch searches without this file
  4. #=============================================================================
  5.  
  6. alpha::mode Brws 1.1.1 dummyBrws 
  7.  
  8. namespace eval browse {}
  9.  
  10. Bind '\r'    browse::Goto  Brws
  11. Bind enter    browse::Goto  Brws
  12. ascii 0x3      browse::Goto  Brws
  13. Bind down     browse::Down Brws
  14. Bind up     browse::Up   Brws
  15. Bind 'n' <z>    browse::Down Brws
  16. Bind 'p' <z>    browse::Up   Brws
  17. ascii 0x20    browse::Down Brws
  18. ascii 0x8    browse::Up   Brws
  19. # this was below.  do we need it?
  20. Bind 'c' <Cz>    browse::Goto
  21.  
  22. proc dummyBrws {} {}
  23.  
  24. # Set this to 1 to test dynamic code
  25. set browse::enableDynamic 0
  26.  
  27. proc browse::Up {} {
  28.     set limit [nextLineStart [nextLineStart [minPos]]]
  29.     if {[pos::compare [getPos] > $limit]} {
  30.     set limit [pos::math [getPos] - 1]
  31.     }
  32.     select [lineStart $limit] [nextLineStart $limit]
  33. }
  34.  
  35. proc browse::Down {} {
  36.     set pos [getPos]
  37.     if {[pos::compare $pos < [nextLineStart [minPos]]]} {
  38.     set pos [nextLineStart [minPos]]
  39.     }
  40.     if {[pos::compare [nextLineStart $pos] < [maxPos]]} {
  41.     select [nextLineStart $pos] [nextLineStart [nextLineStart $pos]]
  42.     }
  43. }
  44.  
  45. proc nextPrevMatch {{dir 1} {wname "*Batch Find*"}} {
  46.     set wins [winNames]
  47.     set res [lsearch $wins $wname]
  48.     if {$res < 0} {
  49.     set res [lsearch -regexp $wins {\*.*\*}]
  50.     if {$res < 0} return
  51.     }
  52.     set win [lindex $wins $res]
  53.     bringToFront $win
  54.     if {$dir} {
  55.     browse::Down
  56.     } else {
  57.     browse::Up
  58.     }
  59.     browse::Goto
  60.     dispErr $win
  61. }
  62.  
  63. proc nextMatch {{wname "*Batch Find*"}} {
  64.     nextPrevMatch 1 $wname
  65. }
  66.  
  67. proc prevMatch {{wname "*Batch Find*"}} {
  68.     nextPrevMatch 0 $wname
  69. }
  70.  
  71. proc dispErr {{win "* Compiler Errors *"}} {
  72.     if {[string length $win]} {
  73.     set text [getText -w $win [getPos -w $win] [selEnd -w $win]]
  74.     if {[regexp {(Line.*)∞} $text dummy sub]} {
  75.         message "$sub"
  76.     }
  77.     }
  78. }
  79.         
  80.  
  81. ##############################################################################
  82. #  To be used in the windows created by "matchingLines" or by batch searches.
  83. #
  84. #  With the cursor positioned in a line corrsponding to a match, 
  85. #  go back and select the line in the original file that 
  86. #  generated this match.  (Like emacs 'Occur' functionality)
  87. #
  88. proc browse::Goto {} {
  89.     global browse::GotoProc
  90.     foreach pat [array names browse::GotoProc] {
  91.     if {[string match $pat [win::CurrentTail]]} {
  92.         [set browse::GotoProc($pat)]
  93.         return
  94.     }
  95.     }
  96.     global tileHeight tileWidth tileTop tileLeft tileHeight \
  97.       errorHeight errorDisp tileMargin
  98.     set loc [getPos]
  99.     set ind1 -1
  100.     while {$ind1 < 0} {
  101.     set text [getText [lineStart $loc] [nextLineStart $loc]]
  102.     set ind1 [string first "∞" $text]
  103.     set loc [nextLineStart $loc]
  104.     if {[pos::compare $loc == [maxPos]]} {break}
  105.     }
  106.     set ind2 [string last "∞" $text]
  107.     if {$ind1 == $ind2} {
  108.     set fname [string trim [string range $text $ind1 end] "∞\r\n"]
  109.     set msg ""
  110.     } else {
  111.     set tmp [string trim [string range $text 0 $ind2] "∞\r\n"]
  112.     if {[string last "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t∞" $tmp] < 0} {
  113.         set fname [string trim [string range $text $ind2 end] "∞\r\n"]
  114.         set msg ""
  115.     } else {
  116.         set ind1 [string last "∞" $tmp]
  117.         set fname [string trim [string range $text $ind1 $ind2] "∞\r\n"]
  118.         set msg [string trim [string range $text $ind2 end] "∞\r\n"]
  119.     }
  120.     }
  121.     set loc [getPos]
  122.     set line -1
  123.     while {1} {
  124.     if {[regexp {Line ([0-9]+):} $text "" line]} {break}
  125.     set text [getText [lineStart $loc] [nextLineStart $loc]]
  126.     set loc [pos::math [lineStart $loc] - 1]
  127.     if {[pos::compare $loc <= [minPos]]} {
  128.         # It's a browse window without line numbers, since we've
  129.         # backed up to the top of the window.
  130.         set line -1
  131.         break
  132.     }
  133.     }
  134.     
  135.     set top $tileTop
  136.     set geo [getGeometry]
  137.     if {([lindex $geo 0] != $tileLeft) || ([lindex $geo 1] != $top) \
  138.       || ([lindex $geo 3] != $errorHeight) } {
  139.     moveWin $tileLeft $top
  140.     sizeWin $tileWidth $errorHeight
  141.     }
  142.     set mar $tileMargin
  143.     incr top [expr {$errorHeight + $mar}]
  144.     if {[browse::OpenWindow $fname]} {
  145.     edit -c -w -g $tileLeft $top $tileWidth $errorDisp $fname
  146.     set geo [getGeometry]
  147.     if {([lindex $geo 0] != $tileLeft) || ([lindex $geo 1] != $top) \
  148.       || ([lindex $geo 2] != $tileWidth) || ([lindex $geo 3] != $errorDisp) } {
  149.         sizeWin $tileWidth $errorDisp
  150.         moveWin $tileLeft $top
  151.     }
  152.     } else {
  153.     if {![string match "*Link*" \
  154.       [getText [minPos] [nextLineStart [minPos]]]]} {
  155.         alertnote "File \"$fname\" not found." 
  156.     }
  157.     return
  158.     }
  159.     if {$line >= 0} {
  160.     set pos [rowColToPos $line 0]
  161.     select $pos [nextLineStart $pos]
  162.     }
  163.     message $msg
  164. }
  165.  
  166. proc browse::OpenWindow {fname} {
  167.     global tileHeight tileWidth tileTop tileLeft tileHeight \
  168.       errorHeight errorDisp tileMargin
  169.     if {[file exists $fname]} {
  170.     set top $tileTop
  171.     set mar $tileMargin
  172.     incr top [expr {$errorHeight + $mar}]
  173.     edit -c -w -g $tileLeft $top $tileWidth $errorDisp $fname
  174.     set geo [getGeometry]
  175.     if {([lindex $geo 0] != $tileLeft) || ([lindex $geo 1] != $top) \
  176.       || ([lindex $geo 2] != $tileWidth) || ([lindex $geo 3] != $errorDisp) } {
  177.         sizeWin $tileWidth $errorDisp
  178.         moveWin $tileLeft $top
  179.     }
  180.     return 1
  181.     } else {
  182.     return 0
  183.     }
  184. }
  185.  
  186. set browse::lastMatchingLines ""
  187.  
  188. proc matchingLines {{reg ""} {for 1} {ign 1} {word 0} {regexp 1}} {
  189.     global browse::lastMatchingLines
  190.     
  191.     if {![string length $reg] && \
  192.       [catch {prompt "Regular expression:" [set browse::lastMatchingLines]} reg]} return
  193.     set browse::lastMatchingLines $reg
  194.     if {![string length $reg]} return
  195.     if {!$regexp} {
  196.     set reg [quote::Regfind $reg]
  197.     }
  198.     if {$word} {
  199.     set reg "^.*\\b$reg\\b.*$"
  200.     } else {
  201.     set reg "^.*$reg.*$"
  202.     }
  203.     set pos [expr {$for ? [minPos] : [getPos]}]
  204.     set fileName [stripNameCount [win::Current]]
  205.     set matches 0
  206.     browse::Start {* Matching Lines *} \
  207.       "%d matching lines (<cr> to go to match)\r-----" 
  208.     while {![catch {search -s -f 1 -r 1 -i $ign -- $reg $pos} mtch]} {
  209.     browse::Add $fileName [eval getText $mtch] \
  210.       [lindex [posToRowCol [lindex $mtch 0]] 0] 0
  211.     set pos [lindex $mtch 1]
  212.     incr matches
  213.     }
  214.     browse::Complete
  215. }
  216.  
  217. ## 
  218.  # -------------------------------------------------------------------------
  219.  # 
  220.  # "grepsToWindow" --
  221.  # 
  222.  #  'args' is a list of items
  223.  # -------------------------------------------------------------------------
  224.  ##
  225. proc grepsToWindow {title args} {
  226.     global tileLeft tileTop tileWidth tileHeight errorHeight
  227.     win::SetProportions
  228.     new -n $title -g $tileLeft $tileTop $tileWidth $errorHeight -m Brws \
  229.       -tabsize 8 -info [join $args ""]
  230.     select [nextLineStart [nextLineStart [minPos]]] [nextLineStart [nextLineStart [nextLineStart [minPos]]]]
  231.     message ""
  232. }
  233.  
  234. ## 
  235.  # -------------------------------------------------------------------------
  236.  # 
  237.  # "browse::Format" --
  238.  # 
  239.  #  Can be used by external code to ensure browse information is in an
  240.  #  acceptable format, and to simplify external code.
  241.  # -------------------------------------------------------------------------
  242.  ##
  243. proc browse::Format {file match line {withname 1}} {
  244.     if {$withname} {
  245.     set l [expr {40 - [string length [file tail $file]]}]
  246.     append res "\"[file tail $file]\"; " [format "%$l\s" ""] " "
  247.     } else {
  248.     regsub -all "\t" $match "  " match
  249.     }
  250.     append res [format "Line %d:\r" $line] $match \
  251.       "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t∞$file"
  252.     return $res
  253. }
  254.  
  255. proc browse::RedoCount {} {
  256.     global browse::prefix browse::count
  257.     replaceText [minPos] [pos::math [minPos] + [string length [format [set browse::prefix] 1]]] \
  258.       [format [set browse::prefix] [set browse::count]]
  259. }
  260.  
  261. proc browse::Complete {} {
  262.     global browse::lines browse::none browse::haveWindow browse::count
  263.     if {[string length [set browse::haveWindow]]} {
  264.     bringToFront [set browse::haveWindow]
  265.     browse::RedoCount
  266.     goto [minPos]
  267.     select [nextLineStart [nextLineStart [minPos]]] [nextLineStart [nextLineStart [nextLineStart [minPos]]]]
  268.     setWinInfo read-only 1
  269.     return 0
  270.     } else {
  271.     if {[set browse::count]} {
  272.         browse::createWindow
  273.         setWinInfo read-only 1
  274.         select [nextLineStart [nextLineStart [minPos]]] [nextLineStart [nextLineStart [nextLineStart [minPos]]]]
  275.         return 0
  276.     } else {
  277.         beep
  278.         message [set browse::none]
  279.         return 1
  280.     }
  281.     }
  282. }
  283.  
  284. proc browse::createWindow {} {
  285.     global tileLeft tileTop tileWidth tileHeight errorHeight \
  286.       browse::lines browse::title browse::prefix browse::haveWindow \
  287.       browse::backGround browse::count
  288.     if {[set browse::backGround]} {set w [win::Current]}
  289.     win::SetProportions
  290.     set browse::haveWindow [new -n [set browse::title] \
  291.       -g $tileLeft $tileTop $tileWidth $errorHeight -m Brws \
  292.       -tabsize 8 -shell 1 \
  293.       -text "[format [set browse::prefix] [set browse::count]]\r[join [set browse::lines] \r]"]
  294.     set browse::lines {}
  295.     if {[set browse::backGround]} {bringToFront $w}
  296.     message ""
  297. }
  298.  
  299. proc browse::updateWindow {} {
  300.     global browse::haveWindow browse::lines
  301.     goto -w [set browse::haveWindow] [maxPos -w [set browse::haveWindow]]
  302.     insertText -w [set browse::haveWindow] "[join [set browse::lines] \r]\r"
  303.     set browse::lines {}
  304. }
  305.  
  306. ## 
  307.  # -------------------------------------------------------------------------
  308.  # 
  309.  # "browse::Add" --
  310.  # 
  311.  #  Add the information to our list of browse items.  We can actually 
  312.  #  add these dynamically to the window if we like.
  313.  # -------------------------------------------------------------------------
  314.  ##
  315. proc browse::Add {file match line {withname 1}} {
  316.     global browse::lines browse::dynamic browse::haveWindow browse::count
  317.     lappend browse::lines [browse::Format $file $match $line $withname]
  318.     incr browse::count
  319.     if {[set browse::dynamic]} {
  320.     if {[string length [set browse::haveWindow]]} {
  321.         browse::updateWindow
  322.     } else {
  323.         browse::createWindow
  324.     }
  325.     }
  326. }
  327.  
  328. ## 
  329.  # -------------------------------------------------------------------------
  330.  # 
  331.  # "browse::Dynamic" --
  332.  # 
  333.  #  Somewhat experimental.
  334.  # -------------------------------------------------------------------------
  335.  ##
  336. proc browse::Dynamic {{backgd 0} {dyn 1}} {
  337.     global browse::dynamic browse::haveWindow browse::backGround browse::enableDynamic
  338.     if {![set browse::enableDynamic]} {return}
  339.     set browse::dynamic $dyn
  340.     set browse::haveWindow ""
  341.     set browse::backGround $backgd
  342. }
  343.  
  344. proc browse::Start {{theTitle {* Matching Lines *}} \
  345.   {thePrefix "%d matching lines (<cr> to go to match)\r-----"} \
  346.   {ifNone "No matches found."}} {
  347.     global browse::lines browse::title browse::prefix browse::none \
  348.       browse::dynamic browse::haveWindow browse::backGround browse::count
  349.     set browse::lines {}
  350.     set browse::title $theTitle
  351.     set browse::prefix $thePrefix
  352.     set browse::none $ifNone
  353.     set browse::dynamic 0
  354.     set browse::haveWindow ""
  355.     set browse::backGround 0
  356.     set browse::count 0
  357. }
  358.  
  359.